package org.xxpay.pay.channel.xx2pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.xxpay.core.common.domain.api.msg.AgentPayBalanceRetMsg;
import org.xxpay.core.common.domain.api.msg.QueryRetMsg;
import org.xxpay.core.common.util.DateUtil;
import org.xxpay.core.common.util.MyLog;
import org.xxpay.core.common.util.PayDigestUtil;
import org.xxpay.core.common.util.XXPayUtil;
import org.xxpay.core.entity.TransOrder;
import org.xxpay.pay.channel.BaseTrans;

import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * @description: xx2pay代付接口
 */
@Service
public class Xx2payTransService extends BaseTrans {

    private static final MyLog _log = MyLog.getLog(Xx2payTransService.class);

    @Override
    public String getChannelName() {
        return Xx2payConfig.CHANNEL_NAME;
    }

    @Override
    public QueryRetMsg trans(TransOrder transOrder) {
        String logPrefix = "【xx2pay代付】";

        Xx2payConfig xx2payConfig = new Xx2payConfig(getTransParam(transOrder));
        JSONObject retObj = buildRetObj();

        try {

            Map<String,Object> paramMap = new TreeMap();
            paramMap.put("mchId", xx2payConfig.getMchId());  //商户ID
            paramMap.put("mchOrderNo", transOrder.getTransOrderId()); //商户代付单号
            paramMap.put("amount", transOrder.getAmount());  //代付金额
            paramMap.put("bankName", transOrder.getBankName());    //银行名称
            paramMap.put("accountName", transOrder.getAccountName()); //收款人账户名
            paramMap.put("accountNo", transOrder.getAccountNo()); //收款人账户号
            paramMap.put("reqTime", DateUtil.date2Str(new Date(), DateUtil.FORMAT_YYYYMMDDHHMMSS));
            paramMap.put("version", "1.0");
            paramMap.put("notifyUrl", super.getNotifyTransUrl(getChannelName(), null));  //代付结果回调URL

            String sign = PayDigestUtil.getSign(paramMap, xx2payConfig.getKey());
            paramMap.put("sign", sign);

            String reqUrl = xx2payConfig.getReqUrlHost() + "/api/agentpay/apply?" + XXPayUtil.genUrlParams(paramMap);
            String resData = XXPayUtil.call4Post(reqUrl);

            if(StringUtils.isBlank(resData)) {
                _log.info("{} >>> 请求没有响应,将转账转为失败", logPrefix);
                return QueryRetMsg.confirmFail(); // 失败
            }

            JSONObject resultObj = JSON.parseObject(resData);
            String retCode = resultObj.getString("retCode");
            String retMsg = resultObj.getString("retMsg");

            if("0".equalsIgnoreCase(retCode)){ //处理成功， 更新为代付中， 转账成功后接收异步通知结果

                // 交易处理中
                _log.info("{} >>> 转账处理中", logPrefix);
                return QueryRetMsg.waiting(); // 处理中

            }else{ //按照失败处理

                retObj.put("channelErrCode", retCode);
                retObj.put("channelErrMsg", retMsg);
                // 交易失败
                _log.info("{} >>> 转账失败", logPrefix);
                return QueryRetMsg.confirmFail();   // 失败
            }

        }catch (Exception e) {
            _log.error(e, "转账异常");
            return QueryRetMsg.sysError();
        }
    }

    public QueryRetMsg query(TransOrder transOrder) {
        String logPrefix = "【xx2pay代付查询】";

        Xx2payConfig xx2payConfig = new Xx2payConfig(getTransParam(transOrder));
        QueryRetMsg retObj ;

        try {

            Map<String,Object> paramMap = new TreeMap();
            paramMap.put("mchId", xx2payConfig.getMchId());  //商户ID
            paramMap.put("mchOrderNo", transOrder.getTransOrderId()); //商户代付单号
            paramMap.put("reqTime", DateUtil.date2Str(new Date(), "yyyyMMddHHmmss")); //请求时间
            paramMap.put("version", "1.0");

            String sign = PayDigestUtil.getSign(paramMap, xx2payConfig.getKey());
            paramMap.put("sign", sign);

            String reqUrl = xx2payConfig.getReqUrlHost() + "/api/agentpay/query_order?" + XXPayUtil.genUrlParams(paramMap);
            String resData = XXPayUtil.call4Post(reqUrl);

            if(StringUtils.isBlank(resData)) {
                _log.info("{} >>> 请求没有响应", logPrefix);
                return QueryRetMsg.waiting(); // 处理中
            }

            JSONObject resultObj = JSON.parseObject(resData);
            // retObj.put("channelObj", resultObj);
            String retCode = resultObj.getString("retCode");
            String retMsg = resultObj.getString("retMsg");
            String retStatus = resultObj.getString("status");
            String agentpayOrderId = resultObj.getString("agentpayOrderId");

            if(!"0".equalsIgnoreCase(retCode)){ //查询失败
                _log.info("{} >>> 查询失败", logPrefix);
                return QueryRetMsg.waiting(); // 处理中
            }

            if("2".equalsIgnoreCase(retStatus)){ // 转账成功
                _log.info("{} >>> 转账成功", logPrefix);
                retObj = QueryRetMsg.confirmSuccess(agentpayOrderId);
                retObj.setChannelOriginResponse(resultObj.toJSONString());
                return retObj;
            }else if("3".equalsIgnoreCase(retStatus)){ //转账失败
                _log.info("{} >>> 转账成功", logPrefix);
                retObj = QueryRetMsg.confirmFail(agentpayOrderId, retCode, retMsg);
                retObj.setChannelOriginResponse(resultObj.toJSONString());
                return retObj;
            }else{
                _log.info("{} >>> 转账中", logPrefix);
                retObj = QueryRetMsg.waiting();
                retObj.setChannelOriginResponse(resultObj.toJSONString());
                return retObj;
            }

        }catch (Exception e) {
            _log.error(e, "查询异常");
            retObj = QueryRetMsg.waiting();
            return retObj;
        }

    }

    @Override
    public AgentPayBalanceRetMsg balance(String payParam) {

        String logPrefix = "【xx2pay代付账户余额查询】";

        Xx2payConfig xx2payConfig = new Xx2payConfig(payParam);
        JSONObject retObj = buildRetObj();

        try {

            Map<String,Object> paramMap = new TreeMap();
            paramMap.put("mchId", xx2payConfig.getMchId());  //商户ID
            paramMap.put("reqTime", DateUtil.date2Str(new Date(), "yyyyMMddHHmmss")); //请求时间
            paramMap.put("version", "1.0");

            String sign = PayDigestUtil.getSign(paramMap, xx2payConfig.getKey());
            paramMap.put("sign", sign);

            String reqUrl = xx2payConfig.getReqUrlHost() + "/api/agentpay/query_balance?" + XXPayUtil.genUrlParams(paramMap);
            String resData = XXPayUtil.call4Post(reqUrl);

            if(StringUtils.isBlank(resData)) {
                _log.info("{} >>> 请求没有响应", logPrefix);
                return AgentPayBalanceRetMsg.fail();
            }

            JSONObject resultObj = JSON.parseObject(resData);
            String retCode = resultObj.getString("retCode");
            if(!"0".equalsIgnoreCase(retCode)){ //查询失败
                _log.info("{} >>> 查询失败", logPrefix);
                return AgentPayBalanceRetMsg.fail();
            }

            return AgentPayBalanceRetMsg.success(
                    Long.parseLong(resultObj.getString("agentpayBalance")), // 现金余额
                    Long.parseLong(resultObj.getString("availableAgentpayBalance")) // 代付可用余额
            );
        }catch (Exception e) {
            _log.error(e, "查询商户余额异常");
            return AgentPayBalanceRetMsg.fail();
        }

    }


}
